library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity pipedereg is
	generic
	(
		DATA_WIDTH	: natural  :=	32;
		REG_WIDTH	: natural  :=	5;
		ALUC_WIDTH	: natural  :=	5
	);

	port
	(
		-- Input ports
		-- from pipeid
		dwreg : in std_logic;
		dm2reg : in std_logic;
		dwmem : in std_logic;
		daluc : in std_logic_vector(ALUC_WIDTH-1 downto 0);
		daluimm : in std_logic;
		da : in std_logic_vector(DATA_WIDTH-1 downto 0);
		db : in std_logic_vector(DATA_WIDTH-1 downto 0);
		dimm : in std_logic_vector(DATA_WIDTH-1 downto 0);
		ddesr : in std_logic_vector(REG_WIDTH-1 downto 0);
		dshift : in std_logic;
		-- from outside
		cen : in std_logic;
		clk : in std_logic;
		clrn : in std_logic;
		
		-- Output ports
		ewreg : out std_logic; -- to pipeemreg and pipeid
		em2reg : out std_logic; -- to pipeemreg and pipeid
		ewmem : out std_logic; -- to pipeemreg		
		-- to pipeexe
		ealuc : out std_logic_vector(ALUC_WIDTH-1 downto 0);
		ealuimm : out std_logic;
		ea : out std_logic_vector(DATA_WIDTH-1 downto 0);
		eb : out std_logic_vector(DATA_WIDTH-1 downto 0);
		eimm : out std_logic_vector(DATA_WIDTH-1 downto 0);
		eshift : out std_logic;
		-- to pipeid and pipeemreg
		edesr : out std_logic_vector(REG_WIDTH-1 downto 0)
	);
end pipedereg;

architecture rtl_pipedereg of pipedereg is
component lpm_dffe32
	PORT
	(
		aclr		: IN STD_LOGIC ;
		clock		: IN STD_LOGIC ;
		data		: IN STD_LOGIC_VECTOR (31 DOWNTO 0);
		enable		: IN STD_LOGIC ;
		q		: OUT STD_LOGIC_VECTOR (31 DOWNTO 0)
	);
end component;
component lpm_dffe5
	PORT
	(
		aclr		: IN STD_LOGIC ;
		clock		: IN STD_LOGIC ;
		data		: IN STD_LOGIC_VECTOR (4 DOWNTO 0);
		enable		: IN STD_LOGIC ;
		q		: OUT STD_LOGIC_VECTOR (4 DOWNTO 0)
	);
end component;
component lpm_dffe1
	PORT
	(
		aclr		: IN STD_LOGIC ;
		clock		: IN STD_LOGIC ;
		data		: IN STD_LOGIC ;
		enable		: IN STD_LOGIC ;
		q		: OUT STD_LOGIC 
	);
end component;
signal aclr: std_logic;
begin
	aclr <= not clrn;
	dewreg_r: lpm_dffe1 port map(
		aclr => aclr,
		clock => clk,
		data => dwreg,
		enable => cen,
		q => ewreg
	);
	dem2reg_r: lpm_dffe1 port map(
		aclr => aclr,
		clock => clk,
		data => dm2reg,
		enable => cen,
		q => em2reg
	);
	dewmem_r: lpm_dffe1 port map(
		aclr => aclr,
		clock => clk,
		data => dwmem,
		enable => cen,
		q => ewmem
	);
	dealuimm_r: lpm_dffe1 port map(
		aclr => aclr,
		clock => clk,
		data => daluimm,
		enable => cen,
		q => ealuimm
	);
	deshift_r: lpm_dffe1 port map(
		aclr => aclr,
		clock => clk,
		data => dshift,
		enable => cen,
		q => eshift
	);	
	dea_r: lpm_dffe32 port map(
		aclr => aclr,
		clock => clk,
		data => da,
		enable => cen,
		q => ea
	);
	deb_r: lpm_dffe32 port map(
		aclr => aclr,
		clock => clk,
		data => db,
		enable => cen,
		q => eb
	);
	deimm_r: lpm_dffe32 port map(
		aclr => aclr,
		clock => clk,
		data => dimm,
		enable => cen,
		q => eimm
	);
	dedesr_r: lpm_dffe5 port map(
		aclr => aclr,
		clock => clk,
		data => ddesr,
		enable => cen,
		q => edesr
	);
	dealuc_r: lpm_dffe5 port map(
		aclr => aclr,
		clock => clk,
		data => daluc,
		enable => cen,
		q => ealuc
	);
end rtl_pipedereg;

